/*
 *  DryRun.c
 */
#include <poll.h>
#include <stdio.h>
#include <netdb.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>

#define BUFFERSIZE 255
#define MAXGUESSES 100

int numPins;
int numColors;
int sockfd;

// structure for a linked list
typedef struct colornode{
	char color[21];
	struct colornode* next;
	struct colornode* previous;
}ColorNode;

ColorNode *colorList=NULL;

// structure for a constraint
typedef struct entry{
	int *code;
	int whites;
	int reds;
}Entry;

// structure for a linked list
typedef struct node{
	char filename[100];
	double number;
	struct node* next;
	struct node* previous;
}Node;

void addEntry(int *code, int whites, int reds){
	
}

void initialize(char* host, char* port){
	struct sockaddr_in serv_addr;
	struct hostent *server;
	int n, rv;
	int len=0;
	int index=0;
	char buffer[BUFFERSIZE+1];
	char color[21];
	char previous[21]="";
	ColorNode *colorInsert=NULL;
	ColorNode *newColor=NULL;
	struct pollfd ufds;
	
	bzero(previous, 21);
	server = gethostbyname(host);
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	bzero((char *) &serv_addr, sizeof(serv_addr));
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_port = htons(atoi(port));
	bcopy((char *)server->h_addr,
		  (char *)&serv_addr.sin_addr.s_addr,
		  server->h_length);
	if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0){
		exit(1);
	}
	n=read(sockfd,buffer,BUFFERSIZE);
	numPins=atoi(buffer);
	numColors=0;
	while(buffer[index]!=';' && index<n){
		index++;
	}
	index++;
	while(n>0){
		while(index+len<n){
			len++;
			if(buffer[index+len]==','){
				newColor=(ColorNode*) malloc(sizeof(ColorNode));
				strncat(previous, &(buffer[index]), len);
				strcpy(newColor->color, previous);
				strcpy(previous, "");
				if(colorList==NULL){
					newColor->previous=NULL;
					colorList=newColor;
				}
				else{
					colorInsert->next=newColor;
					newColor->previous=colorInsert;
				}
				newColor->next=NULL;
				colorInsert=newColor;
				numColors++;
				index=index+len+1;
				len=0;
			}
		}
		strncat(previous, &(buffer[index]), len);
		previous[len]='\0';
		
		ufds.fd = sockfd;
		ufds.events = POLLIN;
		rv = poll(&ufds, 1, 1000);
		if(rv>0){
			n=read(sockfd,buffer,BUFFERSIZE);
		}
		else{
			n=0;
		}
		index=0;
		len=0;
	}
	newColor=(ColorNode*) malloc(sizeof(ColorNode));
	strcpy(newColor->color, previous);
	if(colorList==NULL){
		newColor->previous=NULL;
		colorList=newColor;
	}
	else{
		colorInsert->next=newColor;
		newColor->previous=colorInsert;
	}
	newColor->next=NULL;
	numColors++;
}

void submitGuess(int code[], int* whites, int*reds){
	char submission[numPins*21];
	char buffer[BUFFERSIZE+1];
	int index=0;
	int i, j, len;
	ColorNode *temp;
	
	for(i=0; i<numPins; i++){
		temp=colorList;
		j=0;
		while(j<code[i]){
			if(temp!=NULL){
				temp=temp->next;
			}
			else{
			}
			j++;
		}
		if(i>0){
			strcat(&(submission[index]), ",");
			index++;
		}
		strcpy(&(submission[index]), temp->color);
		index=index+strlen(temp->color);
	}
	strcat(submission, "\n");
	write(sockfd, submission, strlen(submission));
	read(sockfd,buffer,BUFFERSIZE);
	*reds=atoi(buffer);
	index=0;
	len=strlen(buffer);
	while(buffer[index]!=',' && index<len){
		index++;
	}
	index++;
	*whites=atoi(&(buffer[index]));
}

int main(int argc, char *argv[]){
	int randomFailCount=0;
	int reds=0;
	int whites=0;
	int valid=0;
	int guesses=0;
	int i;
	if(argc<3){
		exit(1);
	}
	initialize(argv[1], argv[2]);
	int code[numPins];
	while(randomFailCount<10*(numColors+numPins) && reds<numPins && guesses<MAXGUESSES){
		valid=0;
		while(valid==0 && randomFailCount<10*(numColors+numPins)){
			randomFailCount++;
			for(i=0; i<numPins; i++){
				code[i]=random()%numColors;
			}
			valid=1;
		}
		submitGuess(code, &whites, &reds);
		guesses++;
		printf("Code: %d",code[0]);
		for(i=1; i<numPins; i++){
			printf(", %d",code[i]);
		}
		printf("\nReds: %d\nWhites: %d\n\n",reds, whites);
	}
	close(sockfd);
//	printf("randomFailCount
}